package top.ucat.boots.common.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;
import top.ucat.boots.common.exception.BaseException;
import top.ucat.boots.common.result.Result;
import top.ucat.boots.common.result.SystemResult;

import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 方法参数校验
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Result> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        this.errorShow(e);
        Result result = SystemResult.BAD_REQUEST.getResult(e.getBindingResult().getFieldError().getDefaultMessage(), e.getMessage(), null);
        return ResponseEntity.status(result.getStatus()).body(result);
    }

    /**
     * ValidationException
     */
    @ExceptionHandler(ValidationException.class)
    public ResponseEntity<Result> handleValidationException(ValidationException e) {
        this.errorShow(e);
        Result result = SystemResult.BAD_REQUEST.getResult(e.getCause().getMessage(), e.getMessage(), null);
        return ResponseEntity.status(result.getStatus()).body(result);

    }

    /**
     * ConstraintViolationException
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<Result> handleConstraintViolationException(ConstraintViolationException e) {
        this.errorShow(e);
        Result result = SystemResult.BAD_REQUEST.getResult(e.getMessage(), e.getMessage(), null);
        return ResponseEntity.status(result.getStatus()).body(result);
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    public ResponseEntity<Result> handlerNoFoundException(Exception e) {
        this.errorShow(e);
        Result result = SystemResult.BAD_REQUEST.getResult(404, "路径不存在，请检查路径是否正确", e.getMessage(), null);
        return ResponseEntity.status(result.getStatus()).body(result);
    }

    @ExceptionHandler(DuplicateKeyException.class)
    public ResponseEntity<Result> handleDuplicateKeyException(DuplicateKeyException e) {
        this.errorShow(e);
        Result result = SystemResult.BAD_REQUEST.getResult("数据重复，请检查后提交", e.getMessage(), null);
        return ResponseEntity.status(result.getStatus()).body(result);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<Result> exceptionHandler(Exception e, HttpServletResponse response) {
        this.errorShow(e);
        Result result = null;
        if (false) {
            result = new Result(500, "接口调用超时", e.getLocalizedMessage(), null);
        } else if (e instanceof BaseException) {
            result = new Result(((BaseException) e).getStatus(), e.getMessage(), e.getLocalizedMessage(), null);
        } else {
            result = SystemResult.ERROR.getResult(e.getMessage(), null);
        }
        return ResponseEntity.status(result.getStatus()).body(result);
    }

    void errorShow(Exception e) {
//        e.printStackTrace();
        log.error("", e);
    }
}